#ifndef CAS_H
#define CAS_H


#include <fstream>
#include <map>
#include <string>
#include <vector>
#include <OgreMesh.h>


class Cas
{
public:

	typedef struct
	{
		unsigned short a;
		unsigned short b;
		unsigned short c;
	} Face;

	class Bone
	{
	public:
        std::string name;
		std::string str;
        unsigned int quatFrames;
        unsigned int animFrames;
        unsigned int quatOffset;
        unsigned int animOffset;
        unsigned int zero;
        unsigned int one;
	};

	class Type 
	{
	public:
		enum Index
		{
			DEFAULT,
			NAVY,
			RESOURCE,
			SYMBOL,
			ANIMATION,
			RTW
		};
	};

	class Mesh
	{
	public:
		std::vector<Ogre::Vector3> vertexes;
		std::vector<Ogre::Vector3> normals;
		std::vector<Ogre::Vector2> textureCoords;
		std::vector<Face>          faces;

		unsigned int textureID;
	};

	static std::shared_ptr<Cas> get(std::string filePath, Cas::Type::Index index);
	
	std::string getMeshName();

	std::vector<Mesh> meshes;

protected:
	void parseHeader();
	void parseFileChunk();
	void parseHierarchy();
	void parseTimeTicks();
	void parseBone();
	void parseMeshData();
	void parseFooter();
	
	void parseRTW();
	void parseRTWMeshes();
	void parseRTWTextures();
	std::string parseRTWTextureFileName();

private:
	bool open(std::string filePath, Type::Index typeIndex);
	void prepare();	

	template<typename T>
	void readLE(T* t);

	template<typename T>
	void readLE(std::vector<T>& v, unsigned int length);

	static std::map<std::string, std::shared_ptr<Cas>> filePathMap;

	std::string filePath;
	std::string basePath;
	std::ifstream inputStream;
	Type::Index typeIndex;
	
	float versionNumber;
	char signatureByteTriple2[3];

	unsigned int nFrames;
	std::vector<float> timeTicks;

	unsigned int nSceneBones;

	std::vector<int>   hierarchy;
	std::vector<Bone>  bones;	
	std::vector<float> quatFloats;
	std::vector<float> animFloats;
	std::vector<float> poseFloats;

	unsigned int nMeshes;	
	
	std::vector<std::string> textureFilePaths;

	Ogre::MeshPtr meshPtr;
};

#endif